package com.learning_paicoding.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.learning_paicoding.dto.UserLoginDTO;
import com.learning_paicoding.dto.UserRegisterDTO;
import com.learning_paicoding.entity.User;
import com.learning_paicoding.entity.UserThreadLocal;
import com.learning_paicoding.service.UserService;
import com.learning_paicoding.utils.JWTUtils;
import com.learning_paicoding.utils.RedisCache;
import com.learning_paicoding.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Author hph
 * @Date 2025/10/12 21:56
 **/
@Slf4j
@RestController
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisCache redisCache;



    @PostMapping("/register")
    public Result<String> register(@Valid @RequestBody UserRegisterDTO userRegisterDTO) {
        //1. 打印日志
        log.info("用户注册：{}", userRegisterDTO.getTelephone());
        //2. 密码盐值加密
        String salt = userRegisterDTO.getSalt();
        String password = userRegisterDTO.getPassword();
        String md5Password = DigestUtils.md5DigestAsHex((password + salt).getBytes());
        userRegisterDTO.setPassword(md5Password);

        //3. 生成唯一ID
        // 生成10位ID (使用时间戳后6位 + UUID后4位)
        // 获取时间戳后6位
        long timestamp = System.currentTimeMillis() % 1000000;
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        // 取UUID hash值的后4位数字
        int uuidPart = uuid.hashCode() & 0xFFFF;
        String idStr = String.format("%06d%04d", timestamp, uuidPart);
        Long id = Long.valueOf(idStr);

        //4. 把DTO拷贝到User
        User user = BeanUtil.copyProperties(userRegisterDTO, User.class);
        user.setId(id);
        try {
            userService.save(user);
            return Result.success("注册成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.serverError("注册失败！");
        }
    }


    @PostMapping("/login")
    public Result<Map<String, String>> login(@Valid @RequestBody UserLoginDTO userLoginDTO) {
        log.info("用户登录：{}", userLoginDTO.getTelephone());
        try {
            User userInfo = userService.getByTelephone(userLoginDTO.getTelephone());
            String password = userLoginDTO.getPassword();
            String md5Password = DigestUtils.md5DigestAsHex((password + userInfo.getSalt()).getBytes());
            // 验证密码是否正确
            if (!md5Password.equals(userInfo.getPassword())) {
                return Result.clientError("手机号或密码错误!");
            }
            // 更新用户的最后登录时间、登录方式
            userInfo.setLoginType(1);
            userInfo.setUpdateTime(LocalDateTime.now());
            userService.updateById(userInfo);

            // 生成token, 并保存到Redis中
            String token = JWTUtils.createToken(userInfo.getId());
            redisCache.setCacheObject(token, JSON.toJSONString(userInfo), 300, TimeUnit.SECONDS);
            
            // 构造返回的JSON对象
            Map<String, String> resultMap = new HashMap<>();
            resultMap.put("token", token);
            return Result.success("登录成功！", resultMap);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.serverError("登录失败！");
        }
    }


    @PostMapping("/logout")
    public Result<String> logout(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            return Result.clientError("未提供token或不存在");
        }
        try {
            // 从Redis中删除token
            redisCache.deleteObject(token);

            // 获取当前用户信息并更新登录状态
            User currentUser = UserThreadLocal.get();
            if (currentUser != null) {
                // 将登录状态设置为0（未登录状态）
                currentUser.setLoginType(0);
                userService.updateById(currentUser);
            }
            // 从线程局部变量中移除用户信息
            UserThreadLocal.remove();
            return Result.success("注销登录！");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.serverError("注销失败！");
        }
    }


    /**
     * 验证登录JWT，TOKEN
     * @return
     */
    @GetMapping("/info")
    public Result<User> info() {
        User currentUser = UserThreadLocal.get();
        if (currentUser != null) {
            return Result.success("获取用户信息成功", currentUser);
        } else {
            return Result.unauthorized();
        }
    }



}